package com.qidian.server.socket;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.net.Socket;

import org.apache.log4j.Logger;

import com.qidian.common.Constants;
import com.qidian.server.MServer;
import com.qidian.server.Status;
import com.qidian.util.ByteUtil;


public class FileWorker implements Runnable{

    protected Socket clientSocket = null;
    protected String serverText   = null;
	protected byte[] buf = new byte[Constants.socket_buf_size];
	protected MServer mserver = MServer.getInstance() ;
	
    static Logger logger = Logger.getLogger(FileWorker.class) ;
    
    public FileWorker(Socket clientSocket, String serverText) {
        this.clientSocket = clientSocket;
        this.serverText   = serverText;
    }

    public void run() 
    {
//    	long start = System.currentTimeMillis() ;
    	try 
        {
    		// 设置Socket超时时间
    		clientSocket.setSoTimeout(Constants.socket_time_out) ;
//    		clientSocket.setSoTimeout(3000) ;
    		clientSocket.setReceiveBufferSize(Constants.socket_buf_size) ;
//    		clientSocket.setSoLinger(true, Constants.socket_time_out) ;
    		BufferedInputStream input = new BufferedInputStream(clientSocket.getInputStream());
    		BufferedOutputStream output = new BufferedOutputStream(clientSocket.getOutputStream()) ;
    		
            //InputStream input  = clientSocket.getInputStream();
            //OutputStream output = clientSocket.getOutputStream();
            
            // 发送一个小于64的随机校验字节
            byte randomByte = (byte)(Math.random()*64+1) ;
            output.write(randomByte) ;
            output.flush() ;
            
            // 返回随机校验字节+API编号
            byte backRandomByte = (byte)input.read() ;
            byte apiNo = (byte)(backRandomByte - randomByte) ;
            if(apiNo == 0)
            	sendFile(input,output) ;
            else if (apiNo == 1)
            	report(input,output) ;
            else
            	return ;
        }
        catch (Exception e) 
        {
            e.printStackTrace();
            logger.error(e) ;
        }
        finally{
        	try {
        		if (!clientSocket.isInputShutdown())
        			clientSocket.shutdownInput() ;
        		if (!clientSocket.isOutputShutdown())
        			clientSocket.shutdownOutput() ;
				clientSocket.close() ;
			} catch (IOException e) {
			}
//			System.out.println("Time cost:"+(System.currentTimeMillis()-start)) ;
        }
    }
    private void sendFile(InputStream input, OutputStream output) throws IOException
    {
    	Status status = Status.OK ;
    	
        // 开始处理正式消息
        int totalReadSize = 0 ;
        while(totalReadSize < buf.length)
        {
        	//每次读取1024字节
        	int readCount = input.read(buf,totalReadSize,1024);
        	
        	// 输入流结束
        	if (readCount == -1)
        		break ;
        	
        	totalReadSize += readCount;
        	// 如果超过最大上传长度,停止接收
        	if (totalReadSize >= buf.length)
        		break ;
        }
        // 关闭输入流
        clientSocket.shutdownInput() ;
        
//        System.out.println(totalReadSize);
        // 解析输入流
        int argLen = ByteUtil.readInt(buf, 0) ;
        if (argLen > buf.length)
        {
        	status = Status.INVALID_VALUE ;
        	output.write(status.toString().getBytes()) ;
        	clientSocket.shutdownOutput() ;
        	return ;
        }
        String strArgs = new String(buf,4,argLen);
        String[] args= strArgs.split(Constants.splitString);
//        System.out.println(strArgs);
        if (args == null || args.length < 4)
        {
        	status = Status.INVALID_ARGUMENT ;
        	output.write(status.toString().getBytes()) ;
        	clientSocket.shutdownOutput() ;
        	return ;
        }
        else
        {
        	String account = args[0] ;
        	String contentType = args[1] ;
        	String pGameType = args[2] ;
        	String pInterval = args[3] ;
        	
        	String userName = null ;
        	if (args.length > 4)
        		userName = args[4] ;
        	
        	String fromAddr = clientSocket.getRemoteSocketAddress().toString() ;
        	int indexSplit = fromAddr.indexOf(':');
        	String fromIP = fromAddr.substring(1,indexSplit) ;
        	int fromPort = Integer.parseInt(fromAddr.substring(indexSplit+1)) ;
        	byte[] content = new byte[totalReadSize-4-argLen] ;
//        	System.out.println("argLen"+argLen+",contentLen:"+(totalReadSize-4-argLen)) ;
        	System.arraycopy(buf, 4+argLen, content, 0, content.length) ;
        	int gameType = Integer.parseInt(pGameType) ;
        	int interval = Integer.parseInt(pInterval) ;
        	StringBuffer result = new StringBuffer(32) ;
        	status = mserver.p2s_sendFile(contentType, content,
        			 userName,account, gameType, interval, fromIP, fromPort, 
        			 -1,null,result);
        	if(status == Status.OK)
        		output.write(result.toString().getBytes()) ;
        	else
        		output.write(status.toString().getBytes()) ;
        	output.flush() ;
        	clientSocket.shutdownOutput() ;
        }
    }
    
    /**
     * Format:account#msgId
     * 
     * */
    private void report(InputStream input, OutputStream output) throws IOException
    {
    	Status status = Status.OK ;

        // 开始处理正式消息
        int totalReadSize = 0 ;
        while(totalReadSize < buf.length)
        {
        	//每次读取1024字节
        	int readCount = input.read(buf,totalReadSize,1024);
        	
        	// 输入流结束
        	if (readCount == -1)
        		break ;
        	
        	totalReadSize += readCount;
        	// 如果超过最大上传长度,停止接收
        	if (totalReadSize >= buf.length)
        		break ;
        }
        
    	// account#msgId
        String strArgs = new String(buf,0,totalReadSize);
        String[] args= strArgs.split(Constants.splitString);
        if (args == null || args.length < 2)
        	status = Status.INVALID_ARGUMENT ;
        else
        {
        	String account = args[0] ;
        	String msgId = args[1] ;
        	long id = Long.parseLong(msgId) ;
        	status = mserver.p2s_report(id, account, "0") ;
        	output.write(status.toString().getBytes()) ;
        }    	
    }
}